package main

import (
	"fmt"
	"html/template"
	"io/ioutil"
	"net/http"
	"os"
)

type Article struct {
	ArticleId      int
	ArticleContent string
	ArticleAuthor  string
}

type Person struct {
	Name    string
	Age     int
	Emails  []string
	Company string
	Role    string
}

type OnlineUser struct {
	User      []*Person
	LoginTime string
}

// HandlerA1 示例:变量使用示例
func HandlerA1(w http.ResponseWriter, r *http.Request) {
	t, err := template.ParseFiles("html/args.html")
	if err != nil {
		fmt.Println("err in templeate/ParseFiles:", err.Error())
		os.Exit(-1)
	}

	//1.变量传递  -- 使用Struct域进行变量传递
	err = t.Execute(w, &Article{
		ArticleId:      12,
		ArticleContent: "This is ArticleContent",
		ArticleAuthor:  "zhangsan",
	})
	if err != nil {
		fmt.Println("err in templeate/Execute:", err.Error())
		os.Exit(-1)
	}
	//2.变量传递 -- 使用map[string]interface{} 进行变量传递
	//    err = t.Execute(os.Stdout, map[string]interface{}{
	//        "ArticleAuthor":"zhangsan",
	//    })

}

// HandlerA1 示例:变量使用示例
func HandlerA11(w http.ResponseWriter, r *http.Request) {
	t, err := template.ParseFiles("html/args1.html")
	if err != nil {
		fmt.Println("err in templeate/ParseFiles:", err.Error())
		os.Exit(-1)
	}
	dumx := Person{
		Name:    "zoro",
		Age:     27,
		Emails:  []string{"dg@gmail.com", "dk@hotmail.com"},
		Company: "Omron",
		Role:    "SE"}
	chxd := Person{Name: "chxd", Age: 27, Emails: []string{"test@gmail.com", "d@hotmail.com"}}
	onlineUser := OnlineUser{User: []*Person{&dumx, &chxd}}

	//3.变量传递 -- 使用模板的 with 语句
	err = t.Execute(w, onlineUser)

}

//注入模板的函数
func Add(a, b int) int {
	return a + b
}

func Myname(name string) string {
	return "my name is " + name
}

func NoArgs() string {
	return "This is NoArgs function"
}

// HandlerA2 示例:函数使用示例
func HandlerA2(w http.ResponseWriter, r *http.Request) {
	t := template.New("函数使用示例")
	t.Funcs(map[string]interface{}{
		"add":    Add,
		"myname": Myname,
		"noargs": NoArgs,
	})

	//@ Note:函数的模板读取,使用函数template.ParseFiles时候，会报错:类似`function "add" not defined` 说函数名未定义,原因不明，使用ioutil.ReadFile + template.Parse替换
	b, err := ioutil.ReadFile("html/function.html")
	if err != nil {
		fmt.Println("err in ioutil/ReadFile", err.Error())
		os.Exit(-1)
	}
	template.Must(t.Parse(string(b)))

	t.Execute(w, map[string]interface{}{
		"Args1": 20,
		"Args2": 30,
		"Name":  "zhangrj",
		"isRun": true, //""         //if 判断:是否演示函数使用,string 类型的空表示false
	})
}

func HandlerA3(w http.ResponseWriter, r *http.Request) {
	t, err := template.ParseFiles("html/cycle.html")
	if err != nil {
		fmt.Println("err in template/ParseFiles", err.Error())
		os.Exit(-1)
	}
	m := map[string]interface{}{
		"ID":    12345678,
		"name":  "zhangsan",
		"socre": 97.8,
	}

	err = t.Execute(w, map[string]interface{}{
		"slice":          m,
		"ArticleContent": "This is ArticleContent",
	})
	if err != nil {
		fmt.Println("err in template/Execute", err.Error())
	}
}

func FunctionA() {
	http.HandleFunc("/args", HandlerA1)
	http.HandleFunc("/args1", HandlerA11)
	http.HandleFunc("/function", HandlerA2)
	http.HandleFunc("/cycle", HandlerA3)
	http.ListenAndServe(":8888", nil)
}

//
func main() {
	FunctionA()
}
